package com.tyk.bookstore.back.product.manager.prodcut;

import com.tyk.bookstore.back.common.core.model.type.BinVo;
import com.tyk.bookstore.back.common.dal.mapper.dto.BinDto;
import com.tyk.bookstore.back.common.dal.mapper.dto.SinDto;
import com.tyk.bookstore.back.product.model.constant.ClazzConstant;
import com.tyk.bookstore.back.product.model.entity.ClazzDo;
import com.tyk.bookstore.back.product.repository.ClazzRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

import java.math.BigInteger;
import java.util.*;

/**
 * @author tyk
 * @description 商品模块通用方法
 */
@Component
@RequiredArgsConstructor
public class ProductManager {

    private final ClazzRepository clazzRepository;

    /**
     * 构建分类全称
     */
    public String buildClazzFullName(Long clazzId) {
        BinDto<BigInteger, String> dto = clazzRepository.selectBin1Eq(
                ClazzDo::getParentId, ClazzDo::getName,
                ClazzDo::getId, clazzId,
                ClazzDo.class
        );
        return dto.getV1().longValue() == 0 ? dto.getV2() : buildClazzFullName(dto.getV1().longValue()) + ClazzConstant.CLAZZ_NAME_SEPARATOR + dto.getV2();
    }

    /**
     * 构建分类全称
     */
    public List<BinVo> buildClazzFullName(Set<Long> clazzIdList) {
        HashMap<Long, String> map = new HashMap<>();
        return clazzIdList.stream().map(it -> {
            String name = buildClazzFullName(it, map);
            return new BinVo(it, name);
        }).toList();
    }

    /**
     * 构建分类全称
     *
     * @param clazzId 分类ID
     * @param map     缓存
     * @return 分类全称
     */
    private String buildClazzFullName(Long clazzId, Map<Long, String> map) {
        BinDto<BigInteger, String> dto = clazzRepository.selectBin1Eq(
                ClazzDo::getParentId, ClazzDo::getName,
                ClazzDo::getId, clazzId,
                ClazzDo.class
        );
        String funllName = dto.getV2();
        if (dto.getV1().longValue() != 0) {
            funllName = buildClazzFullName(dto.getV1().longValue(), map) + ClazzConstant.CLAZZ_NAME_SEPARATOR + funllName;
        }
        map.put(clazzId, funllName);
        return funllName;
    }


    /**
     * 查询当前分类所在各级分类名称
     */
    public List<BinVo> buildClazzNameVoList(Long clazzId) {
        List<BinVo> clazzBinVoList = new ArrayList<>();
        com.tyk.bookstore.back.common.dal.mapper.dto.BinDto<BigInteger, String> dto = clazzRepository.selectBin1Eq(
                ClazzDo::getParentId, ClazzDo::getName,
                ClazzDo::getId, clazzId,
                ClazzDo.class
        );
        if (dto.getV1().longValue() != 0L) clazzBinVoList.addAll(buildClazzNameVoList(dto.getV1().longValue()));
        clazzBinVoList.add(new BinVo(clazzId, dto.getV2()));
        return clazzBinVoList;
    }


    /**
     * 找到以ancestorId为根结点的分类树的所有结点
     */
    public List<Long> findClazzOffspringIdList(Long ancestorId) {
        List<Long> ids = new ArrayList<>();
        clazzRepository
                .<Long>selectSinList1Eq(
                        ClazzDo::getId,
                        ClazzDo::getParentId, ancestorId,
                        ClazzDo.class
                ).forEach(it -> ids.addAll(findClazzOffspringIdList(it.getV1())));
        ids.add(ancestorId);
        return ids;
    }

    /**
     * 找到以ancestorId为根结点的分类树的所有叶子
     */
    public List<Long> findClazzLeafIdList(Long ancestorId) {
        List<Long> ids = new ArrayList<>();
        List<Long> subIdList = clazzRepository.<Long>selectSinList1Eq(
                ClazzDo::getId,
                ClazzDo::getParentId, ancestorId,
                ClazzDo.class
        ).stream().map(SinDto::getV1).toList();
        if (!subIdList.isEmpty())
            subIdList.forEach(subId -> ids.addAll(findClazzLeafIdList(subId)));
        else
            ids.add(ancestorId);
        return ids;
    }
}
